/**
 * 
 */
package jmine.tec.rpc.sync;

import java.io.Serializable;
import java.util.Arrays;

/**
 * Um comando enviado para sistemas que desejam estar sincronizados
 * 
 * @author takeshi
 */
public abstract class DatabaseSynchronizationCommand implements Serializable {

    private final String[] sourceClassHierarchy;

    private final Long sourceId;

    private final Serializable naturalKey;

    /**
     * C'tor
     * 
     * @param sourceClassHierarchy a hierarquia de classes da entidade modificada
     * @param id o id da entidade modificada
     * @param naturalKey a naturalKey (se aplicavel)
     */
    public DatabaseSynchronizationCommand(String[] sourceClassHierarchy, Long id, Serializable naturalKey) {
        super();
        this.sourceClassHierarchy = sourceClassHierarchy;
        this.sourceId = id;
        this.naturalKey = naturalKey;
    }

    /**
     * C'tor
     * 
     * @param sourceClassHierarchy a hierarquia de classes
     * @param id o id
     */
    public DatabaseSynchronizationCommand(String[] sourceClassHierarchy, Long id) {
        this(sourceClassHierarchy, id, null);
    }

    /**
     * @return array de {@link String}
     */
    public String[] getSourceClassHierarchy() {
        String[] result = new String[sourceClassHierarchy.length];
        System.arraycopy(sourceClassHierarchy, 0, result, 0, sourceClassHierarchy.length);
        return result;
    }

    /**
     * @return the sourceId
     */
    public Long getSourceId() {
        return this.sourceId;
    }

    /**
     * @return the naturalKey
     */
    public Serializable getNaturalKey() {
        return this.naturalKey;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((this.naturalKey == null) ? 0 : this.naturalKey.hashCode());
        result = prime * result + Arrays.hashCode(this.sourceClassHierarchy);
        result = prime * result + ((this.sourceId == null) ? 0 : this.sourceId.hashCode());
        return result;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (this.getClass() != obj.getClass()) {
            return false;
        }
        DatabaseSynchronizationCommand other = (DatabaseSynchronizationCommand) obj;
        if (this.naturalKey == null) {
            if (other.naturalKey != null) {
                return false;
            }
        } else if (!this.naturalKey.equals(other.naturalKey)) {
            return false;
        }
        if (!Arrays.equals(this.sourceClassHierarchy, other.sourceClassHierarchy)) {
            return false;
        }
        if (this.sourceId == null) {
            if (other.sourceId != null) {
                return false;
            }
        } else if (!this.sourceId.equals(other.sourceId)) {
            return false;
        }
        return true;
    }

}